#! user/bin/python
# -*- coding: utf-8 -*-

"""
Created on 2021/8/19 17:49

@File: 使套接字看起来像文件和数据流_流重定向实用程序_socket_stream_redirect.py
@Author: LT
@Description: Use of this module
"""
#####################################################################################################
# 用于连接非GUI程序的标准流到一个套接字的工具，
# 一个GUI（或其他）程序可以使用这个与非GUI程序进行交互
# 重定向是做了sys.stdout = file = sock.makefile("w" or "r")   这一步的！！！！！！！！！！！！！！！！！！！！
#####################################################################################################
import sys
from socket import *
port = 50008
host = 'localhost'
waitnums = 5                                        # 允许服务器忙时，可等待连接的客户端连接数


def initListenerSocket(port=port):
    """
    初始化在服务器模式下调用者用于监听的连接套接字，bind，listen，accept三连
    """
    sock = socket(AF_INET, SOCK_STREAM)
    sock.bind((host, port))
    sock.listen(waitnums)                           # 使服务器可以接收客户端的连接同时设定...允许等待的数量
    connection, address = sock.accept()             # 返回连接上的套接字就行了
    return connection


def redirectOut(port=port, host=host):
    """
    在接收之前其他连接失败，连接调用者标准输出流到一个套接字，
    这个套接字用于GUI监听，在收听者启动后，启动调用者
    """
    sock = socket(AF_INET, SOCK_STREAM)
    sock.connect((host, port))
    file = sock.makefile("w")                       # 文件接口：text，buffered
    sys.stdout = file                               # 让print的内容重定向到sock.send里
    return sock


def redirectIn(port=port, host=host):
    """
    连接调用者标准输入流到用于GUI来提供功能的套接字
    """
    sock = socket(AF_INET, SOCK_STREAM)
    sock.connect((host, port))
    file = sock.makefile("r")
    sys.stdin = file                                # 让input重定向到sys.stdin里
    return sock


def redirectBothAsClient(port=port, host=host):
    """
    在这种模式下，连接调用者标准输入和输出流到相同的套接字，
    调用者对于服务器来说就是客户端：发送消息，接收响应答复
    """
    sock = socket(AF_INET, SOCK_STREAM)
    sock.connect((host, port))
    ofile = sock.makefile("w")
    ifile = sock.makefile("r")
    sys.stdout = ofile
    sys.stdin = ifile
    return sock


def redirectBothAsServer(port=port, host=host):
    """
    在这种模式下，连接调用者标准输入和输出流到相同的套接字，
    调用者对于客户端来说就是服务器：接收消息，发送响应答复
    """
    sock = socket(AF_INET, SOCK_STREAM)
    sock.bind((host, port))
    sock.listen(waitnums)
    connection, address = sock.accept()
    ofile = connection.makefile("w")
    ifile = connection.makefile("r")
    sys.stdout = ofile
    sys.stdin = ifile
    return connection
